// PersistentModify.cpp: implementation of the PersistentModify class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "PersistentModify.h"
#include "Volume.h"
#include "AssocCommon.h"
#include "Part.h"
#include "Supporthanger.h"
#include "Joint.h"
#include "Project.h"
#include "ProjectManager.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
using namespace PropertySystem;
namespace PersistentObjectOperation
{
	PersistentModify::PersistentModify()
	{
		
	}
	
	PersistentModify::~PersistentModify()
	{
		
	}
	
	BOOL PersistentModify::Visit(Volume*& pVolume)
	{
		ASSERT(pVolume);
		ASSERT(pVolume->IsModifyState());

		CString strSql;
		strSql.Format(_T("Update [Volume] Set VolumeName = '%s', Description = '%s'\
			where VolumeID = '%d'"),
			pVolume->Name(), pVolume->Description(), pVolume->VolumeID());

		try
		{
			const _ConnectionPtr& pCon = this->ProjectConnection(pVolume->project());
			pCon->Execute(_bstr_t(strSql), NULL, adCmdText);
		}
		catch(_com_error e)
		{
			ASSERT(FALSE);
			ErrorAlert(e);
			return FALSE;
		}
		return TRUE;
	}
	
	BOOL PersistentModify::Visit(Part*& pPart)
	{
		ASSERT(pPart);
		ASSERT(pPart->IsModifyState());

		SupportHanger* pSH = pPart->SupportHangerOwner();

		AcGePoint3d OriginalPt;
		AcGeVector3d vX;
		AcGeVector3d vY;
		AcGeVector3d vZ;

		AcGeMatrix3d matrix = pPart->ModelMatrix();
		matrix.getCoordSystem(OriginalPt, vX, vY, vZ);
		
		CString strSql;
		strSql.Format(_T("Update [Parts_Of_SupportHanger] Set PF_ID = '%s', Part_Standard_ID = '%s' ,\
						Pos_X = '%g', Pos_Y = '%g', Pos_Z = '%g',\
						Dir_X_X = '%g', Dir_X_Y = '%g', Dir_X_Z = '%g',\
						Dir_Z_X = '%g', Dir_Z_Y = '%g', Dir_Z_Z = '%g' where SH_ID = '%s' and Part_ID = %d"),
						pPart->GetCustomID(), pPart->GetStandard(),
						OriginalPt.x, OriginalPt.y, OriginalPt.z,
						vX.x, vX.y, vX.z,
						vZ.x, vZ.y, vZ.z,
						pPart->SupportHangerOwner()->SupportHangerID(),
						pPart->PartIndex());

		this->PersistentExecute(strSql, pPart->project());
		pPart->SetRead();
		
		return this->UpdatePartProperties(pPart);
	}
	
	BOOL PersistentModify::UpdatePartProperties(SupportHangerSubObject* pPart)
	{
		BOOL bResult = TRUE;
		ASSERT(pPart);
		PropertyStack* pStack = pPart->GetPropertyStack();
		ASSERT(pStack);

		CString strSql;
		SupportHanger* pSH = pPart->SupportHangerOwner();
		ASSERT(pSH);

		ASSERT(!pSH->SupportHangerID().IsEmpty());
		ASSERT(!pSH->GetSupportHangerPoint().VolumeID().IsEmpty());

		SaveProperty(pStack, pSH->SupportHangerID(), pPart->Id());

		return TRUE;
	}

	void PersistentModify::SaveProperty(PropertySystem::PropertyStack* pStack, const CString& strSHID, const UeObjectId& id)
	{
		PropertyStack::Iterator* pIterator = pStack->NewSavePropertyIterator();
		if(pIterator == NULL)
		{
			ASSERT(pIterator);
			::ReportMemoryError();
		}

		BOOL bResult = FALSE;
		CString strSql;
		for(pIterator->Begin(); !pIterator->End(); pIterator->Next())
		{
			Variable* pVar = pIterator->Get();
			ASSERT(pVar);
			ASSERT(!pVar->GetSymbol().IsEmpty());
			ASSERT(!vtos((_variant_t)(*pVar)).IsEmpty());;
			
			strSql.Format(_T("Update [Properties_Of_Part] Set Property_Value = '%s' where\
							Part_ID = %d and Property_ID = '%s'"),
							vtos((_variant_t)(*pVar)),
							(INT)id, pVar->GetSymbol());

			bResult = PersistentExecute(strSql, GetProjectManager().CurProject());
			ASSERT(bResult);

		}
		delete pIterator;
		return;
	}

	BOOL PersistentModify::Visit(SupportHanger*& pSH)
	{
		ASSERT(pSH);
		ASSERT(pSH->IsModifyState());

		CString strSql;
		strSql.Format(_T("Update [SupportHanger] Set SH_EntryPart_ID = '%d',IsCheckOut = %s\
			where SH_ID = '%s' and SH_VolumeID = '%s'"),
			pSH->SupportHangerEntry()->PartIndex(),
			pSH->IsCheckOut()?_T("true"):_T("false"),
			pSH->SupportHangerID(),
			pSH->GetSupportHangerPoint().VolumeID());
		
		pSH->SetRead();
		SaveProperty(pSH->GetPropertyStack(), pSH->SupportHangerID(), pSH->Id());

		return this->PersistentExecute(strSql, pSH->project());
	}
	
	BOOL PersistentModify::Visit(Joint*& pJoint)
	{
		ASSERT(pJoint);

/*		Joint::Iterator* pIt = pJoint->NewAttachIterator();
		ASSERT_MEMORY_VALID(pIt, FALSE);

		for(pIt->Begin(); !pIt->End(); pIt->Next())
		{
			Part* pPart = pIt->Get();
			ASSERT(pPart);

			ASSERT(pJoint->project());
			ASSERT(pJoint->project()->versionController());
			pPart->Accept(&pJoint->project()->versionController()->CurPersistentVisitor());
		}
		delete pIt;//*/

		return UpdatePartProperties(pJoint);
	}
	

	/////////////////////////////////////////////////////////////////////////
	
	PersistentModifyBatch::PersistentModifyBatch()
	{
	}
	
	PersistentModifyBatch::~PersistentModifyBatch()
	{
	}
	
	void PersistentModifyBatch::EndPersistent()
	{
	}
	
	void PersistentModifyBatch::SaveVolume()
	{
	}
	void PersistentModifyBatch::SaveSH()
	{
	}
	void PersistentModifyBatch::SaveJoint()
	{
	}
	void PersistentModifyBatch::SavePart()
	{
	}
	void PersistentModifyBatch::SaveProperty(PropertySystem::PropertyStack* pStack, const CString& strSHID, const UeObjectId& id)
	{
	}
	void PersistentModifyBatch::InitPropertyPtr()
	{
	}
}